package jmine.tec.performance.test;

/**
 * Class to get the use of memory in the system.
 * 
 * @author bruno.ortiz
 */
public class MemoryUsageCalculator {

    private static final float NUMBER_1024 = 1024;

    private boolean runGC = false;

    /**
     * Constructor.
     * 
     * @param runGC true if you want to run the garbage collector before getting the metrics.
     */
    public MemoryUsageCalculator(boolean runGC) {
        this.runGC = runGC;
    }

    public MemoryUsageCalculator() {
    }

    /**
     * Returns the maximum amount of memory that the Java virtual machine will attempt to use.
     */
    public float getMaxMemory() {
        this.runGcIfNecessary();
        return Runtime.getRuntime().maxMemory() / (NUMBER_1024 * NUMBER_1024);
    }

    /**
     * Returns the total amount of memory in the Java virtual machine, runs GC if necessary.
     */
    public float getTotalMemory() {
        this.runGcIfNecessary();
        return totalMemory();
    }

    /**
     * Returns the total amount of memory in the Java virtual machine.
     */
    private float totalMemory() {
        return Runtime.getRuntime().totalMemory() / (NUMBER_1024 * NUMBER_1024);
    }

    /**
     * Returns the amount of free memory in the Java Virtual Machine, runs GC if necessary.
     */
    public float getFreeMemory() {
        this.runGcIfNecessary();
        return freeMemory();
    }

    /**
     * Returns the amount of free memory in the Java Virtual Machine.
     */
    private float freeMemory() {
        return Runtime.getRuntime().freeMemory() / (NUMBER_1024 * NUMBER_1024);
    }

    /**
     * Returns the ammount of memory that the system is currently using.
     */
    public float getUsedMemory() {
        this.runGcIfNecessary();
        return totalMemory() - freeMemory();
    }

    /**
     * Runs GC if necessary.
     */
    private void runGcIfNecessary() {
        if (runGC) {
            System.gc();
        }
    }

}
